package com.shycloud.mido.common.pay.wxpay;

import com.shycloud.mido.common.pay.wxpay.utils.PayCommonUtil;
import com.shycloud.mido.common.pay.wxpay.utils.WxConfigUtil;
import com.shycloud.mido.common.pay.wxpay.utils.XMLUtil;
import lombok.experimental.UtilityClass;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.JDOMException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;

/**
 * Description:微信支付接口
 * Author:THP
 * Date:2019/04/23 15:58
 */
@UtilityClass
public class WXH5Pay {
    private static Log logger = LogFactory.getLog(WXH5Pay.class);
    private static final String UTF ="UTF-8";
    private static final String SUCCESS ="SUCCESS";
    private static final String RESULT_CODE ="result_code";
    /**
     * 微信支付
     * @param price 总金额
     * @param body  商品描述
     * @param notifyUrl 回调地址
     * @param outTradeNo 订单号
     * @return R
     */
    public static Map<String, Map> wxPrePay(String price, String body, String notifyUrl,String outTradeNo ,HttpServletRequest request) {
        Map<String, Map> resultMap = new HashMap<String, Map>();
        Map<String, Object> flag = new TreeMap<>();
        SortedMap<Object, Object> parameters = new TreeMap<>();
        //调用创建统一下单签名
//        if("true".equals(PayCommonUtil.createUnifiedSign(price,body,notifyUrl,outTradeNo,request).get("flag"))) {*/
            parameters = createH5UnifiedSign(price, body, notifyUrl,outTradeNo, request);
//        }
        //封装请求参数结束
        String requestXML = PayCommonUtil.getRequestXml(parameters);
		System.out.println("\n" + parameters);
		System.out.println("\n" + requestXML);
        //调用统一下单接口
        String result = PayCommonUtil.httpsRequest(WxConfigUtil.UNIFIED_ORDER_URL, "POST", requestXML);
        System.out.println("\n" + result);
        try {
            /**统一下单接口返回正常的prepay_id，再按签名规范重新生成签名后，将数据传输给APP。参与签名的字段名为appId，partnerId，prepayId，nonceStr，timeStamp，package。注意：package的值格式为Sign=WXPayNative**/
            Map<String, String> map = XMLUtil.doXMLParse(result);
            SortedMap<Object, Object> parameterMap2 = new TreeMap<Object, Object>();
//            parameterMap2.put("appid", WxConfigUtil.APPIDH5);
//            parameterMap2.put("partnerid", WxConfigUtil.MCH_IDH5);
//            parameterMap2.put("prepayid", map.get("prepay_id"));
//            parameterMap2.put("package", "Sign=WXPayNative");
//            parameterMap2.put("noncestr", PayCommonUtil.createNoncestr());
//            //本来生成的时间戳是13位，但是ios必须是10位，所以截取了一下
//            parameterMap2.put("timestamp", String.valueOf(System.currentTimeMillis()));
//            String sign2 = PayCommonUtil.createSign("UTF-8", parameterMap2);
//			parameterMap2.put("out_trade_no",outTradeNo);
//            parameterMap2.put("sign", sign2);

            flag.put("flag", true);
            resultMap.put("flag", flag);
            resultMap.put("wxPay", parameterMap2);
            return resultMap;
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultMap;
    }
	/**
	 * 创建统一下单签名map
	 * @param request
	 * @return
	 */
	public static SortedMap<Object, Object> createH5UnifiedSign(String price, String body, String notifyUrl,String outTradeNo,HttpServletRequest request) {
		SortedMap<Object, Object> map = new TreeMap<>();
		int price100 = new BigDecimal(price).multiply(new BigDecimal(100)).intValue();
		if (price100 <= 0) {
			map.put("flag", "false");
			return map;
		}
		map.put("appid", WxConfigUtil.APPIDH5);
		map.put("mch_id",WxConfigUtil.MCH_IDH5);
//		map.put("attach","");
//		map.put("detail","");
//		map.put("openid","");
		map.put("nonce_str", PayCommonUtil.createNoncestr());
		map.put("body", body);
		map.put("out_trade_no", outTradeNo);
		map.put("total_fee", String.valueOf(price100));
		map.put("spbill_create_ip",  PayCommonUtil.getIPAddress(request));
//		map.put("notify_url",notifyUrl);
		map.put("notify_url","https://api.happyzebra.sc.fnchi.cn/wxpay/notify.php");

		map.put("trade_type", "NATIVE");
		//商品ID
		String random1 = getRandomString(32);//待用

		map.put("product_id", random1);

//		map.put("scene_info", "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"https://pay.qq.com\",\"wap_name\": \"佳音课程购买\"}}");
		//设置签名
		String sign = PayCommonUtil.createSignH5("UTF-8", map);
		map.put("sign",sign);
//        map.put("flag", "true");
		return map;
	}
    /**
     * 微信支付
     * @return R
     */
    public static Map<String, String> wxNotify(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {
        //读取参数
        boolean flag = false;
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        in.close();
        inputStream.close();
        //解析xml成map
        Map<String, String> m = new HashMap<String, String>();
        m = XMLUtil.doXMLParse(sb.toString());
        for (Object keyValue : m.keySet()) {
            System.out.println(keyValue + "=" + m.get(keyValue));
        }
        return m;
    }
	public static String getRandomString(int length){
		//1.  定义一个字符串（A-Z，a-z，0-9）即62个数字字母；
//		String str="zxcvbnmlkjhgfdsaqwertyuiopQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
		String str="1234567890";
		//2.  由Random生成随机数
		Random random=new Random();
		StringBuffer sb=new StringBuffer();
		//3.  长度为几就循环几次
		for(int i=0; i<length; ++i){
			//从62个的数字或字母中选择
//			int number=random.nextInt(62);
			int number=random.nextInt(10);
			//将产生的数字通过length次承载到sb中
			sb.append(str.charAt(number));
		}
		//将承载的字符转换成字符串
		return sb.toString();
	}
    /**
     * 微信支付
     * @return R
     */
    public static boolean wxNotify(Map<String,String> m,String payStatus, HttpServletRequest request,HttpServletResponse response) throws IOException, JDOMException {
        boolean flag = true;
        //过滤空 设置 TreeMap
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        Iterator it = m.keySet().iterator();
        while (it.hasNext()) {
            String parameter = (String) it.next();
            String parameterValue = m.get(parameter);
            String v = "";
            if (null != parameterValue) {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }
        //判断签名是否正确
        String resXml = "";
        if (PayCommonUtil.isTenpaySign(UTF, packageParams)) {
            if (SUCCESS.equals((String) packageParams.get(RESULT_CODE))) {
                     resXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                     logger.info("订单已处理");
                     flag = true;
                     return flag;
                 }
            }

//        if (PayCommonUtil.isTenpaySign("UTF-8", packageParams)) {
//            if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
//                // 这里是支付成功
//                //商户号
//                String mchId = (String) packageParams.get("mch_id");
//                //用户标识
//                String openId = (String) packageParams.get("openid");
//                //商户订单号
//                String outTradeNo = (String) packageParams.get("out_trade_no");
//                String totalFee = (String) packageParams.get("total_fee");
//                //微信支付订单
//                String transactionId = (String) packageParams.get("transaction_id");
//                if (!WxConfigUtil.MCH_ID.equals(mchId) ||  new BigDecimal(totalFee).compareTo(new BigDecimal(price).multiply(new BigDecimal(100))) != 0) {
//                    logger.info("支付失败,错误信息：" + "参数错误");
//                    resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
//                            + "<return_msg><![CDATA[参数错误]]></return_msg>" + "</xml> ";
//                } else {
//                    if ("0".equals(payStatus)) {
//                        //支付的价格
//                        //订单状态的修改。根据实际业务逻辑执行
//                        resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
//                                + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
//                        flag = true;
//                        return flag;
//
//                    } else {
//                        resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
//                                + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
//                        logger.info("订单已处理");
//                        flag = true;
//                        return flag;
//                    }
//                }
//            } else {
//                logger.info("支付失败,错误信息：" + packageParams.get("err_code"));
//                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
//                        + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
//                return flag;
//            }
//
//
//        } else {
//            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
//                    + "<return_msg><![CDATA[通知签名验证失败]]></return_msg>" + "</xml> ";
//            logger.info("通知签名验证失败");
//            return flag;
//        }
        //------------------------------
        //处理业务完毕
        //------------------------------
        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
        return flag;
    }
}


